package com.tmxbase.examserver.dao;

import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.Item;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.io.InputStream;

@Repository("oSSDAO")
public class OSSDAO {

    private static Logger logger = LoggerFactory.getLogger(OSSDAO.class);

    @Autowired
    private MinioClient minioClient;

    private void ensureBucketExist(String bucketName) {
        try {
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!found) {
                minioClient.makeBucket(MakeBucketArgs.builder()
                        .bucket(bucketName)
                        .build());
            }
        } catch (Exception e) {
            logger.error("[OSSDAO] {}", e);
        }
    }
    /**
     * 上传文件
     * @param bucketName
     * @param fileName
     * @param is
     */
    public void putObject(String bucketName, String fileName, InputStream is)  {
        ensureBucketExist(bucketName);
        try {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(fileName)
                            .stream(is, is.available(), -1)
                            .build()
            );
        } catch (Exception e) {
            logger.error("[OSSDAO] {}", e);
        }
    }

    /**
     * 获取对象
     * @param bucketName
     * @param fileName
     */
    public InputStream getObject(String bucketName, String fileName) {
        ensureBucketExist(bucketName);
        try {
            return minioClient.getObject(
                    GetObjectArgs.builder()
                            .bucket(bucketName)
                            .object(fileName)
                            .build()
            );
        } catch (Exception e) {
            logger.error("[OSSDAO] {}", e);
        }
        return null;
    }

    /**
     * 删除文件
     * @param bucketName
     * @param fileName
     */
    public void deleteObject(String bucketName, String fileName)  {
        ensureBucketExist(bucketName);
        try {
            minioClient.removeObject(
                    RemoveObjectArgs.builder()
                            .bucket(bucketName)
                            .object(fileName)
                            .build()
            );
        } catch (Exception e) {
            logger.error("[OSSDAO] {}", e);
        }
    }

    /**
     * 拷贝文件
     * @param fromBucketName
     * @param toBucketName
     * @param fileName
     */
    public void copyObject(String fromBucketName, String toBucketName, String fileName)  {
        ensureBucketExist(toBucketName);
        try {
            minioClient.copyObject(
                    CopyObjectArgs.builder()
                            .bucket(toBucketName)
                            .object(fileName)
                            .source(
                                    CopySource.builder()
                                            .bucket(fromBucketName)
                                            .object(fileName)
                                            .build())
                            .build());
        } catch (Exception e) {
            logger.error("[OSSDAO] {}", e);
        }
    }

    /**
     * 获取下载URL
     * @param bucketName
     * @param fileName
     * @return
     */
    public String getFileUrl(String bucketName, String fileName) {
        try {
            return minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .bucket(bucketName)
                            .object(fileName)
                            .method(Method.GET)
                            .expiry(300)
                            .build());
        } catch (Exception e) {
            logger.error("[OSSDAO] {}", e);
        }
        return null;
    }

    /**
     * 清空某个bucket
     * @param bucketName
     */
    public void clearBucket(String bucketName) {
        ensureBucketExist(bucketName);
        try {
            // 递归列举某个bucket下的所有文件，然后循环删除
            Iterable<Result<Item>> iterable = minioClient.listObjects(ListObjectsArgs.builder()
                    .bucket(bucketName)
                    .recursive(true)
                    .build());
            for (Result<Item> itemResult : iterable) {
                deleteObject(bucketName, itemResult.get().objectName());
            }
        } catch (Exception e) {
            logger.error("", e);
        }
    }

}
